package com.niiwoo.civet.trade.service.local.plan;

import com.niiwoo.civet.base.enums.FeeTypeEnum;
import com.niiwoo.civet.trade.dao.entity.*;
import com.niiwoo.civet.trade.dao.mapper.ProjectBorrowerPlanDetailMapperExt;
import com.niiwoo.civet.trade.enums.*;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

public abstract class AbstractBorrowerInvestorRepaymentManager implements BorrowerInvestorRepaymentManager {

    protected ProjectBorrowerPlanNew buildProjectBorrowerPlanNew(Long id, Long projectId, String userId, Long accountId, Date refundDate, Integer period, Byte periodType, Integer totalPeriod) {
        ProjectBorrowerPlanNew projectBorrowerPlanNew = new ProjectBorrowerPlanNew();
        projectBorrowerPlanNew.setId(id);
        projectBorrowerPlanNew.setProjectId(projectId);
        projectBorrowerPlanNew.setUserId(userId);
        projectBorrowerPlanNew.setAccountId(accountId);
        projectBorrowerPlanNew.setRefundDate(refundDate);
        projectBorrowerPlanNew.setPeriod(period);
        projectBorrowerPlanNew.setPeriodType(periodType);
        projectBorrowerPlanNew.setTotalPeriod(totalPeriod);
        projectBorrowerPlanNew.setStatus(BorrowerPlanRefundStatusEnum.NON_REPAYMENT.getCode());
        projectBorrowerPlanNew.setCreateTime(new Date());
        projectBorrowerPlanNew.setUpdateTime(new Date());
        return projectBorrowerPlanNew;
    }

    protected ProjectBorrowerPlanDetail buildProjectBorrowerPlanDetail(Long id, Long projectId, String userId, Long planId, Integer feeType, BigDecimal money) {
        ProjectBorrowerPlanDetail projectBorrowerPlanDetail = new ProjectBorrowerPlanDetail();
        projectBorrowerPlanDetail.setId(id);
        projectBorrowerPlanDetail.setProjectId(projectId);
        projectBorrowerPlanDetail.setUserId(userId);
        projectBorrowerPlanDetail.setPlanId(planId);
        projectBorrowerPlanDetail.setFeeType(feeType);
        projectBorrowerPlanDetail.setRefundMoney(BigDecimal.ZERO);
        projectBorrowerPlanDetail.setMoney(money);
        projectBorrowerPlanDetail.setCreateTime(new Date());
        projectBorrowerPlanDetail.setUpdateTime(new Date());
        return projectBorrowerPlanDetail;
    }

    protected void updateBorrowerCapitalInterest(ProjectBorrowerPlanDetailMapperExt projectBorrowerPlanDetailMapperExt, Map<Integer, BigDecimal> investCapitalTotal,
                                               Map<Integer, BigDecimal> investInterestTotal, List<ProjectBorrowerPlanNew> projectBorrowerPlanNewList) {
        for (ProjectBorrowerPlanNew projectBorrowerPlanNew : projectBorrowerPlanNewList) {
            ProjectBorrowerPlanDetail capitalDetail = projectBorrowerPlanDetailMapperExt.queryProjectBorrowerPlanDetailByPlanIdAndFeeType(projectBorrowerPlanNew.getId(), FeeTypeEnum.CAPITAL.getValue().intValue());
            if(capitalDetail != null) {
                ProjectBorrowerPlanDetail updateCapitalRecord = new ProjectBorrowerPlanDetail();
                updateCapitalRecord.setId(capitalDetail.getId());
                updateCapitalRecord.setMoney(investCapitalTotal.get(projectBorrowerPlanNew.getPeriod()));
                projectBorrowerPlanDetailMapperExt.updateByPrimaryKeySelective(updateCapitalRecord);
            }
            ProjectBorrowerPlanDetail interestDetail = projectBorrowerPlanDetailMapperExt.queryProjectBorrowerPlanDetailByPlanIdAndFeeType(projectBorrowerPlanNew.getId(), FeeTypeEnum.INTEREST.getValue().intValue());
            if(interestDetail != null) {
                ProjectBorrowerPlanDetail updateInterestRecord = new ProjectBorrowerPlanDetail();
                updateInterestRecord.setId(interestDetail.getId());
                updateInterestRecord.setMoney(investInterestTotal.get(projectBorrowerPlanNew.getPeriod()));
                projectBorrowerPlanDetailMapperExt.updateByPrimaryKeySelective(updateInterestRecord);
            }
        }
    }

    protected InvestorCreditor buildInvestorCreditor(Long id, Project project, ProjectInvestOrder projectInvestOrder,
                                                      Date firstReceivedDate, BigDecimal firstInterest, Date expectOverDate,
                                                      BigDecimal capital, BigDecimal interest){
        InvestorCreditor investorCreditor = new InvestorCreditor();
        investorCreditor.setId(id);
        investorCreditor.setInvestOrderId(projectInvestOrder.getId());
        investorCreditor.setProjectId(project.getProjectId());
        investorCreditor.setBorrowUserId(project.getBorrowUserId());
        investorCreditor.setProjectType(project.getBorrowerType());
        investorCreditor.setInvestUserId(projectInvestOrder.getUserId());
        investorCreditor.setBorrowRate(project.getBorrowRate());
        investorCreditor.setAddRate(projectInvestOrder.getAddRate());
        investorCreditor.setRepaymentType(project.getRepaymentType());
        investorCreditor.setTransferFrequency(0);
        investorCreditor.setStatus(InvestorCreditorStatusEnum.NORMAL_RECEIVING.getStatus());
        investorCreditor.setCurrentPeriod(1);
        investorCreditor.setTotalPeriod((RepaymentTypeEnum.enumOf(project.getRepaymentType()).equals(RepaymentTypeEnum.REPAY_PRINCIPAL_INTEREST_AT_TERM) ? 1 : project.getDeadline()));
        investorCreditor.setReceivedPeriod(0);
        investorCreditor.setReceivedDate(firstReceivedDate);
        investorCreditor.setCurrentInterest(firstInterest);
        investorCreditor.setExpectOverDate(expectOverDate);
        investorCreditor.setCapital(capital);
        investorCreditor.setInterest(interest);
        investorCreditor.setTotalPenaltyFee(BigDecimal.ZERO);
        investorCreditor.setReceivedCapital(BigDecimal.ZERO);
        investorCreditor.setReceivedInterest(BigDecimal.ZERO);
        investorCreditor.setReceivedPenaltyFee(BigDecimal.ZERO);
        investorCreditor.setCreateTime(new Date());
        investorCreditor.setUpdateTime(new Date());
        return investorCreditor;
    }
}
